<?php
/**
 * Created by PhpStorm.
 * User: Season
 * Date: 2018/10/24
 * Time: 15:38
 */

namespace app\api\service;


use app\api\model\OrderProduct;
use app\api\model\Product;
use app\api\model\UserAddress;
use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderExcption;
use app\lib\exception\UserExcption;
use think\Db;
use think\Exception;
use app\api\model\Order as OrderModel;

class Order
{
    //订单的商品列表
    protected $oProducts;
    //真是的商品信息
    protected $products;

    protected  $uid;

    public function place($uid , $oProducts){
        $this->oProducts = $oProducts;
        $this->products = $this->getProductByOrder($oProducts);
        $this->uid = $uid;
        $status = $this->getOrderStatus ();
        if(!$status['pass']){
            $status['order_id'] = -1;
            return $status;
        }
        //创建订单
        $orderSnap = $this->snapOrder($status);
        $orderSnap = $this->creatOrder($orderSnap);
        $orderSnap['pass'] = true;
        return $orderSnap;
    }

    private function creatOrder($snap){
        Db::startTrans ();
        try {
            $orderNo = self::makeOrderNo ();
            $order = new \app\api\model\Order();
            $order->user_id = $this->uid;
            $order->order_no = $orderNo;
            $order->total_price = $snap[ 'orderPrice' ];
            $order->total_count = $snap[ 'totalCount' ];
            $order->snap_img = $snap[ 'snapImg' ];
            $order->snap_name = $snap[ 'snapName' ];
            $order->snap_address = $snap[ 'snapAddress' ];
            $order->snap_items = json_encode ( $snap[ 'pStatus' ] );

            $order->save ();

            $orderID = $order->id;
            $create_time = $order->create_time;

            foreach ($this->oProducts as &$p) {
                $p[ 'order_id' ] = $orderID;
            }
            $orderProduct = new OrderProduct();
            $orderProduct->saveAll ( $this->oProducts );
            Db::commit ();
            return [
                'order_no' => $orderNo ,
                'order_id' => $orderID ,
                'create_time' => $create_time ,
                'productStaus' => $snap[ 'pStatus' ]
            ];
        }catch (Exception $e){
            Db::rollback ();
            throw $e;
        }
    }

    public static function makeOrderNo()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
        $orderSn =
            $yCode[intval(date('Y')) - 2018] . strtoupper(dechex(date('m'))) . date(
                'd') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf(
                '%02d', rand(0, 99));
        return $orderSn;
    }

    //生成订单快照
    private function snapOrder($status){
        $snap = [
            'orderPrice' => 0,
            'totalCount' => 0,
            'pStatus' => [],
            'snapAddress' => null,
            'snapName' => '',
            'snapImg' => '',
        ];
        $snap['orderPrice'] = $status['orderPrice'];
        $snap['totalCount'] = $status['totalCount'];
        $snap['pStatus'] = $status['pStatusArray'];
        $snap['snapAddress'] = json_encode ($this->getUserAddress ());
        $snap['snapName'] = $this->products[0]['name'];
        $snap['snapImg'] = $this->products[0]['main_img_url'];

        if(count ($this->products) > 1){
            $snap['snapName'] .= '等';
        }
        return $snap;
    }

    //地址
    private function getUserAddress(){
        $userAddress = UserAddress::where('user_id','=',$this->uid)->find ();
        if(!$userAddress){
            throw new UserExcption(
                [
                    'mag' => '用户地址不存在',
                    'errorCode' => 60001
                ]);
        }
        return $userAddress->toArray ();
    }

    private function getOrderStatus(){
        $status = [
            'pass' => true,
            'orderPrice' => 0,
            'totalCount' => 0,
            'pStatusArray' => [],//保存订单商品详情
        ];

        foreach ($this->oProducts as $oProduct){
            $pStatus = $this->getProductStatus(
                $oProduct['product_id'],
                $oProduct['count'],
                $this->products
            );
            if(!$pStatus['haveStock']){
                $status['pass'] = false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            $status['totalCount'] += $pStatus['counts'];
            array_push ($status['pStatusArray'],$pStatus);
        }
        return $status;
    }

    private function getProductStatus($oPID, $oCount, $products){
        $pIndex = -1;
        $pStatus = [
            'id' => null,
            'haveStock' => false,
            'counts' => 0,
            'price' => 0,
            'name' => '',
            'totalPrice' => 0,//同类商品小计
            'main_img_url' => null
        ];

        for($i = 0; $i< count($products);$i++){
            if($oPID == $products[$i]['id']){
                $pIndex = $i;
            }
        }
        if($oPID == -1){
            throw new OrderExcption(
                [
                    'msg' => 'ID为'.$oPID.'商品不存在，创建订单失败'
                ]
            );
        }else{
            $product = $products[$pIndex];
            $pStatus['id'] = $product['id'];
            $pStatus['name'] = $product['name'];
            $pStatus['counts'] = $oCount;
            $pStatus['price'] = $product['price'];
            $pStatus['totalPrice'] = $product['price'] * $oCount;
            $pStatus['main_img_url'] = $product['main_img_url'];
            if($product['stock'] - $oCount >= 0 ){
                $pStatus['haveStock'] = true;
            }
            return $pStatus;
        }
    }

    private function getProductByOrder($oProducts){
        $oPIDs = [];
        foreach ($oProducts as $item) {
            array_push($oPIDs, $item['product_id']);
        }
        $products = Product::all ($oPIDs)
            ->visible(['id', 'price', 'stock', 'name', 'main_img_url'])
            ->toArray();
        return $products;
    }

    public function checkOrderStock($orderID){
        $oProducts = OrderProduct::where('order_id', '=', $orderID)
            ->select ();
        $this->oProducts = $oProducts;
        $this->products = $this->getProductByOrder ($oProducts) ;
        $status = $this->getOrderStatus ();
        return $status;
    }

    public function delivery($orderID, $jumpPage = '')
    {
        $order = OrderModel::where('id', '=', $orderID)
                           ->find();
        if (!$order) {
            throw new OrderExcption();
        }
        if ($order->status != OrderStatusEnum::PAID) {
            throw new OrderException([
                                         'msg' => '还没付款呢，想干嘛？或者你已经更新过订单了，不要再刷了',
                                         'errorCode' => 80002,
                                         'code' => 403
                                     ]);
        }
        $order->status = OrderStatusEnum::DELIVERED;
        $order->save();
//            ->update(['status' => OrderStatusEnum::DELIVERED]);
        $message = new DeliveryMessage();
        return $message->sendDeliveryMessage($order, $jumpPage);
    }
}